package main;

import org.jibble.pircbot.*;
import eRepublik.*;
import bot.*;
import java.sql.*;
import java.util.*;

public class MyBot extends PircBot {
    
	//Start the bot classes
	bot bot = new bot();
	Citizen cit = new Citizen();
	misc misc = new misc();
	general general = new general();
	
	Timer timer;
	
    public MyBot() {
    	this.setName("eRepBot");
    	
    	/*Setup timer messasges    	
        TimedMessageTask tmt1 = new TimedMessageTask("2For eRepBot commands type !help or visit http://wiki.erepublik.com/index.php/ERepBot");
        TimedMessageTask tmt2 = new TimedMessageTask("4eRepBot is still in beta and under development. Please report bugs to Darkmantle (#eRepBot)");

        //Initiate timers - milliseconds!
        timer = new Timer();
        timer.schedule(tmt1, 0, 60 * 60 * 1000);  // Every 1 hour
        timer.schedule(tmt2, 30 * 60 * 1000, 60 * 60 * 1000);  // 30-min offset, every 1 hour*/
    }
    
    class TimedMessageTask extends TimerTask {
        private String message = "";
        
        //Set message
        
        public TimedMessageTask(String message) {
            this.message = message;
        }
        
        //Notice each channel with the message
        public void run() {
        	String[] channels = getChannels();
        	for(int x=0; x < channels.length; x++) {
        		sendMessage(channels[x], message);
        	}
        }
    }
	
	//Declare generic error strings that will be used more than once
	String[] error ={	"4Error: Only bot administrators can use this command!", 
						"4Error: Only channel operators or above can use this command!", 
						"4Error: There is a fault within the API. Please try again soon.",
						"4Error: Citizen does not exist or cannot be found.",
						"4Error: Only channel owners can use this command!.",
						"4MySQL Error: Please try again in a moment. If the issue persists please join #eRepBot for help.",
						"4Error: This IRC nick is not linked, please see !help eRepublik for more information."
					};
					
	//For using the erpk API system
	String apikey = "IshVQwOx";
	
	protected void onConnect() {
		//Identify and joinChans
		sendRawLine("NICKSERV IDENTIFY mantle123countdrak");

		List<String> chans = bot.getChans();
		for (String chan : chans) {
			sendRawLine("JOIN " + chan);
		}
	}
	
	/*
	 * Checks whether the user is op in a channel. More advanced than built-in method.
	 */
	public boolean isOp(String channel, String sender) {
		boolean check = false;
		// Get a list of the users
		User[] users = getUsers(channel);
		
		for(int i = 0; i < users.length; i++) {
			//Assign single user
			String user = users[i].getNick();
			String prefix = users[i].getPrefix();
			
			String user2 = user.replaceAll("[~+&]", "");

			if (user2.equals(sender)) {
				//Check if their name begins with an op prefix
				if (user.startsWith("~") || user.startsWith("&") || prefix.equals("@")) {
					check = true;
				}
			}
		}
		return check;
	}
	
	/*
	 * Method to check if an IRC name is linked to an eRepublik name
	 */
	public String checkLink(String sender) {
		String id = "";

		Connection con = general.getmySQLConnection();
		try {
			// Get row from database
			Statement st = con.createStatement();
			
			ResultSet results = st.executeQuery("SELECT * FROM users WHERE irc = '" + sender.toLowerCase() + "'");
			
			if (results.next()) {
				if (results.getString(1).equals(sender.toLowerCase())) {
					// Get eRepublik ID from the row
					id = results.getString(3);
				}
			} else {
				id = "Error";
			}
			con.close();
		} catch (SQLException s){
			// Database error?
			id = error[5];
		}
		return id;
	}
	
	public String getNameFromID(String id) {
		String citname = "";

		Connection con = general.getmySQLConnection();
		try {
			// Get row from database
			Statement st = con.createStatement();
			
			ResultSet results = st.executeQuery("SELECT * FROM users WHERE id = '" + id + "'");
			results.last();
			
			if (results.getString(3).equals(id)) {
				// Get eRepublik name from the row
				citname = results.getString(2);
			} else {
				citname = "Error";
			}
			con.close();
		} catch (SQLException s){
			// Database error?
			citname = error[5];
		}
		return citname;
	}
	/*
	 * Check that the user is owner in the channel
	 */
	public boolean isOwner(String channel, String sender) {
		boolean check = false;
		//Get user list
		User users[] = getUsers(channel);
		
		for(User user : users){
			String u = user.getNick();
			if (u.indexOf(sender) > 0) {
				//Check if their name begins with an op prefix
				if (u.startsWith("~")) {
					check = true;
				}
			}
		}
		return check;
	}
	
    public void onMessage(String channel, String sender, String login, String hostname, String message) {
    	
    	if (message.startsWith("@") && (channel.equals("#ultrahq") || channel.equals("#UM-QM"))) {
    		 Runnable um = new ultramarines(this, channel, sender, message);
    	     new Thread(um).start();
    	}
					   
		// quit command
		if (message.equalsIgnoreCase("!die")) {
			if (bot.isBotAdmin(hostname) == true) {
				//leave the server
				sendRawLine("QUIT :ERRAH! L2JAVUH!");
				//quit java
			System.exit(-1);
			} else {
				//Error if not admin
				sendMessage(channel, error[0]);
			}
		}
		
		if (message.toLowerCase().startsWith("!count")) {
			if (bot.isBotAdmin(hostname) == true) {
				
				String[] channels = getChannels();
				String send = "10eRepBot is currently in " + channels.length + " channels";
				sendMessage(channel,send);
				
			} else {
				//Error if not admin
				sendMessage(channel, error[0]);
			}
		}
		
		/*if (message.toLowerCase().startsWith("!wall")) {
			message = message.replace("!wall ","");
			int id = Integer.parseInt(message);
			try {
				String[] battle = battles.getBattleData(id);
				for (String send : battle) {
					sendMessage(channel,send);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}*/
		
		//For admin notices
		if (message.toLowerCase().startsWith("!warn")) {
			if (bot.isBotAdmin(hostname) == true) {
				message = message.replace("!warn ","");
				// Get all channels and loop through
				String[] channels = getChannels();

		    	for(int x=0; x < channels.length; x++) {
		    		sendMessage(channels[x], message);
		    	}
			} else {
				//Error if not admin
				sendMessage(channel, error[0]);
			}
		}
		
		//Join command
		if (message.toLowerCase().startsWith("!join ")) {
			//Split to get channel/pass
			String[] temp = message.split(" ",2);
			//Join room
			sendRawLine("JOIN " + temp[1]);
		}
		
		//Part command
		if (message.toLowerCase().startsWith("!part ")) {
			//Split to get channel
			String[] temp = message.split(" ",2);
			//Leave room
			sendRawLine("PART " + temp[1]);
		}
		
		//uptime command		   
		if (message.equalsIgnoreCase("!uptime")) {
			String send = bot.uptime(hostname);
			sendMessage(channel,send);
		}
		
		//Mass Command
		if (message.toLowerCase().startsWith("!mass")) {
			String[] msg = null;
			if (!message.toLowerCase().equals("!mass")) {
				msg = message.split(" ",2);
				msg[1] = "4" + msg[1];
			}
			String send = "";
			if (isOp(channel,sender) == true) {
				//Get users within the channel
				User[] info = getUsers(channel);
				String users = "7Mass Ping:12 ";
				//Loop through users
				for(int i =0; i < info.length ; i++) {
					users = users + info[i] + " ";
				}
				send = users;
			} else {
				//Send error if not channel op
				send = error[1];
			}
			sendMessage(channel,send);
			if (!message.toLowerCase().equals("!mass")) {
				sendMessage(channel,msg[1]);
			}
        }
		
		//Lookup citizen data using their ID. Name search is not working yet.
		if (message.toLowerCase().startsWith("!lookup") || message.toLowerCase().startsWith("!lp")) {
			
			//Variables
			String id = null;
			
			//Check for tags			
			Map<String, String> tags = bot.getTags(message);
			
			//Check if name is entered
			if (tags.get("name") == null) {
				id = checkLink(sender);
			} else {
				id = cit.citizenSearch(tags.get("name").trim());
			}
			
			if (tags.get("name") == null && id.equals("Error")) {
				sendMessage(channel,error[6]);
			} else if (tags.get("name") != null && id.indexOf("exist") > 0) {
				sendMessage(channel,error[3]);
			} else {
				String send = cit.citizenLookup(id);
				sendMessage(channel,send);
			}
		}
		
		//Lookup citizen and return links
		if (message.toLowerCase().startsWith("!link")) {
			
			//Variables
			String id = null;
			String citname = null;
			
			//Check for tags			
			Map<String, String> tags = bot.getTags(message);
			
			//Check if name is entered
			if (tags.get("name") == null) {
				id = checkLink(sender);
				citname = getNameFromID(id);
			} else {
				id = cit.citizenSearch(tags.get("name").trim());
				citname = tags.get("name");
			}
			
			if (tags.get("name") == null && id.equals("Error")) {
				sendMessage(channel,error[6]);
			} else if (tags.get("name") != null && id.indexOf("exist") > 0) {
				sendMessage(channel,error[3]);
			} else {
				String send =  citname+" ["+id+"] 3|| 2Profile: http://www.erepublik.com/en/citizen/profile/"+id
						+ " 3|| 2Donate Items: http://www.erepublik.com/en/economy/donate-items/"+id
						+ " 3|| 2Donate Money: http://www.erepublik.com/en/economy/donate-money/"+id;
				sendMessage(channel,send);
			}
		}
		
		if (message.toLowerCase().startsWith("!fc")) {
			
			//Variables
			String id = "";
			int fights = 1;
			int rank = 0;
			double str = 0;
			
			//Check for tags			
			Map<String, String> tags = bot.getTags(message);
			
			if (tags.get("-f") != null) {
				fights = Integer.parseInt(tags.get("-f"));
			}
			
			if (tags.get("-r") != null) {
				rank = Integer.parseInt(tags.get("-r"));
			}
			
			if (tags.get("-s") != null) {
				str = Double.parseDouble(tags.get("-s"));
			}
			
			//Check if name is entered
			if (tags.get("name") == null) {
				id = checkLink(sender);
			} else {
				id = cit.citizenSearch(tags.get("name").trim());
			}
			
			if (tags.get("name") == null && id.equals("Error")) {
				sendMessage(channel,error[6]);
			} else if (tags.get("name") != null && id.indexOf("exist") > 0) {
				sendMessage(channel,error[3]);
			} else {
				String send = cit.fightCalc(id,fights,rank,str);
				sendMessage(channel,send);
			}
		}
		
		if (message.toLowerCase().startsWith("!dmg")) {
			
			//Variables
			String id = "";
			int rank = 0;
			
			//Check for tags			
			Map<String, String> tags = bot.getTags(message);
			
			if (tags.get("-r") != null) {
				rank = Integer.parseInt(tags.get("-r"));
			}
			
			//Check if name is entered
			if (tags.get("name") == null) {
				id = checkLink(sender);
			} else {
				id = cit.citizenSearch(tags.get("name").trim());
			}
			
			if (tags.get("name") == null && id.equals("Error")) {
				sendMessage(channel,error[6]);
			} else if (tags.get("name") != null && id.indexOf("exist") > 0) {
				sendMessage(channel,error[3]);
			} else {
				String send = cit.dmgCalc(id,rank);
				sendMessage(channel,send);
			}
		}
		
		if (message.toLowerCase().startsWith("!fights")) {
			
			//Variables
			String id = "";
			Map<String, String> tags = bot.getTags(message);
			
			//Check if name is entered
			if (tags.get("name") == null) {
				id = checkLink(sender);
			} else {
				id = cit.citizenSearch(tags.get("name").trim());
			}
			
			if (tags.get("name") == null && id.equals("Error")) {
				sendMessage(channel,error[6]);
			} else if (tags.get("name") != null && id.indexOf("exist") > 0) {
				sendMessage(channel,error[3]);
			} else {
				String send = cit.fightsLeft(id);
				sendMessage(channel,send);
			}
		}
		
		//Command to make bot stay in a room, only owner can use it
		if (message.toLowerCase().startsWith("!stay")) {
			//get chan & pass
			String[] temp = message.split(" ");
			String chan = temp[1];
			String pass = "";
			//Check if pass is set, if not assign as null
			if (temp.length == 2) {
				pass = null;
			} else {
				pass = temp[2];
			}
			
			//Check if the person requesting is owner of channel
			if (isOwner(chan,sender) == true || bot.isBotAdmin(hostname) == true) {
				Connection con = general.getmySQLConnection();
				try{
					//If so, update the database to add channel
					Statement st = con.createStatement();
					st.executeUpdate("REPLACE INTO channels VALUES('"+chan+"','"+pass+"')");
					sendMessage(chan,"eRepBot is now added to " + chan + " and will join here automatically!");
					con.close();
				} catch (SQLException s){
					//Database error?
					sendMessage(chan,error[5]);
				}

			} else {
				//If not owner, send error message
				sendMessage(chan,error[4]);
			}
		}
		
		//Command to make bot leave a room and not auto-join, only owner can use it
				if (message.toLowerCase().startsWith("!leave")) {
					//get chan & pass
					String[] temp = message.split(" ");
					String chan = temp[1];
					
					//Check if the person requesting is owner of channel
					if (isOwner(chan,sender) == true || bot.isBotAdmin(hostname) == true) {
						Connection con = general.getmySQLConnection();
						try{
							//If so, update the database to add channel
							Statement st = con.createStatement();
							st.executeUpdate("DELETE FROM channels WHERE chan = '"+chan+"'");
							sendMessage(chan,"eRepBot has now been removed from " + chan + " and will no longer join here automatically!");
							sendRawLine("PART " + chan);
							con.close();
						} catch (SQLException s){
							//Database error?
							sendMessage(chan,error[5]);
						}

					} else {
						//If not owner, send error message
						sendMessage(chan,error[4]);
					}
				}
		
		// Register eRep name to IRC name
		if (message.toLowerCase().startsWith("!register") && !message.equalsIgnoreCase("!register")) {
			//get citizen name
			String[] citname = message.split(" ",2);
			String id = cit.citizenSearch(citname[1].trim());
			if (id.indexOf("exists") > 0) {
				sendMessage(channel,error[3]);
			} else {
				Connection con = general.getmySQLConnection();
				try{
					//Add to database. Using "REPLACE INTO" will overwrite any duplicates
					Statement st = con.createStatement();
					st.executeUpdate("REPLACE INTO users VALUES('"+sender.toLowerCase()+"','"+citname[1]+"','"+id+"')");
					sendMessage(channel,"Citizen " + citname[1] + " has now been registered to " + sender + "!");
					con.close();
				} catch (SQLException s){
					//Database error?
					sendMessage(channel,error[5]);
				}
			}
		}
		
		// Help command
		if (message.toLowerCase().startsWith("!help")) {
			
			String[] help = null;
			
			if (message.equalsIgnoreCase("!help")) {
				help = misc.help("other");
			} else {
				String[] str = message.split(" ",2);
				help = misc.help(str[1]);
			}
			
			for (String send : help) {
				sendMessage(channel,send);
			}
		}
		
    }
}